<template>
  <div class="timeline-section">
    <div class="timeline-header">
      <h3>📅 {{ title }}</h3>
    </div>
    <div class="timeline-container">
      <div class="timeline">
        <div
          v-for="(item, index) in timelineData"
          :key="index"
          :class="['timeline-item', { abnormal: isAbnormalItem(item) }]"
          :data-index="index"
          @click="showDetail(item)"
        >
          <div class="timeline-date">{{ formatDate(getDateFromItem(item)) }} ({{ getWeekday(getDateFromItem(item)) }})</div>
          <div class="data-list">
            <div
              v-for="metric in metricsList"
              :key="metric.key"
              :class="['data-item', {
                  abnormal: isAbnormal(item[metric.key], metric.key),
                  normal: !isAbnormal(item[metric.key], metric.key)
                }]">
              <span class="label">{{ metric.label }}：</span>
              <span class="value">{{ item[metric.key] }} {{ metric.unit }}</span>
              <span class="change">
                <span :class="getChangeClass(item[metric.key], metric.key, timelineData[index+1] ? timelineData[index+1][metric.key] : null)">
                  {{ getChangeText(item[metric.key], timelineData[index+1] ? timelineData[index+1][metric.key] : null) }}
                </span>
              </span>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: 'HealthTimeline',
  props: {
    title: {
      type: String,
      default: '健康数据时间轴'
    },
    timelineData: {
      type: Array,
      default: () => []
    },
    metricsList: {
      type: Array,
      default: () => [
        { key: 'hr', label: '心率', unit: 'bpm' },
        { key: 'sbp', label: '收缩压', unit: 'mmHg' },
        { key: 'dbp', label: '舒张压', unit: 'mmHg' },
        { key: 'glucose', label: '血糖', unit: 'mmol/L' },
        { key: 'sleep', label: '睡眠', unit: '小时' },
        { key: 'steps', label: '步数', unit: '步' }
      ]
    }
  },
  methods: {
    showDetail(item) {
      this.$emit('show-detail', item);
    },

    // 异常检测函数
    isAbnormal(val, type) {
      if (type === 'hr') return val > 100 || val < 60
      if (type === 'sbp') return val > 140
      if (type === 'dbp') return val > 90 || val < 60
      if (type === 'glucose') return val > 6.1 || val < 3.9
      if (type === 'sleep') return val < 6
      if (type === 'steps') return val < 5000
      return false
    },

    // 检查整个数据项是否有异常
    isAbnormalItem(item) {
      return this.isAbnormal(item.hr, 'hr') ||
             this.isAbnormal(item.sbp, 'sbp') ||
             this.isAbnormal(item.dbp, 'dbp') ||
             this.isAbnormal(item.glucose, 'glucose') ||
             this.isAbnormal(item.sleep, 'sleep') ||
             this.isAbnormal(item.steps, 'steps')
    },

    // 获取日期对象
    getDateFromItem(item) {
      return new Date(item.time)
    },

    // 格式化日期
    formatDate(date) {
      return date.getFullYear() + '年' + (date.getMonth() + 1) + '月' + date.getDate() + '日 ' +
        date.getHours().toString().padStart(2, '0') + ':' +
        date.getMinutes().toString().padStart(2, '0') + ':' +
        date.getSeconds().toString().padStart(2, '0')
    },

    // 获取星期几
    getWeekday(date) {
      const weekdays = ['周日', '周一', '周二', '周三', '周四', '周五', '周六']
      return weekdays[date.getDay()]
    },

    // 获取变化文本
    getChangeText(current, previous) {
      if (previous === null || previous === undefined) return ''

      const diff = current - previous
      if (diff > 0) {
        return '↑ ' + Math.abs(diff).toFixed(diff % 1 === 0 ? 0 : 1)
      } else if (diff < 0) {
        return '↓ ' + Math.abs(diff).toFixed(diff % 1 === 0 ? 0 : 1)
      } else {
        return '→ 0'
      }
    },

    // 获取变化类名
    getChangeClass(current, type, previous) {
      if (previous === null || previous === undefined) return 'same'

      const diff = current - previous
      const isCurrentAbnormal = this.isAbnormal(current, type)

      if (diff > 0) {
        return isCurrentAbnormal ? 'up-abnormal' : 'up-normal'
      } else if (diff < 0) {
        return isCurrentAbnormal ? 'down-abnormal' : 'down-normal'
      } else {
        return 'same'
      }
    }
  }
}
</script>

<style scoped>
.timeline-section {
  flex: 1;
  min-width: 350px;
  display: flex;
  flex-direction: column;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, .1);
  overflow: hidden;
  border: 1px solid #ebeef5;
}

.timeline-header {
  padding: 15px 20px;
  border-bottom: 1px solid #ebeef5;
  background: #f5f7fa;
}

.timeline-header h3 {
  margin: 0;
  color: #303133;
  font-size: 16px;
  font-weight: 600;
}

.timeline-container {
  flex: 1;
  overflow-y: auto;
  max-height: calc(100vh - 250px);
  padding: 15px;
}

.timeline {
  position: relative;
  padding: 15px 0;
}

.timeline::before {
  content: '';
  position: absolute;
  left: 26px;
  top: 0;
  bottom: 0;
  width: 2px;
  background: #ebeef5;
  z-index: 0;
}

.timeline-item {
  position: relative;
  margin: 20px 0;
  padding-left: 55px;
  z-index: 1;
  cursor: pointer;
  transition: all 0.3s;
  border-radius: 4px;
  padding: 15px 20px 15px 55px;
  border: 1px solid transparent;
}

.timeline-item:hover {
  background: #f5f7fa;
  border-color: #dcdfe6;
  transform: translateY(-2px);
  box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
}

.timeline-item::before {
  content: '';
  position: absolute;
  left: 22px;
  top: 20px;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  background: #409eff;
  border: 3px solid #fff;
  box-shadow: 0 0 0 1px #409eff;
  z-index: 2;
}

.timeline-item.abnormal {
  background-color: #fef0f0;
  border-color: #fbc4c4;
}

.timeline-item.abnormal::before {
  background: #f56c6c;
  box-shadow: 0 0 0 1px #f56c6c;
}

.timeline-date {
  font-weight: 600;
  color: #409eff;
  font-size: 14px;
  margin-bottom: 12px;
  padding: 4px 10px;
  background: #ecf5ff;
  border-radius: 4px;
  display: inline-block;
}

.data-list {
  background: #fff;
  border-radius: 4px;
  padding: 12px;
  border: 1px solid #ebeef5;
}

.data-item {
  padding: 8px 0;
  font-size: 13px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-bottom: 1px dashed #ebeef5;
}

.data-item:last-child {
  border-bottom: none;
}

.data-item .label {
  color: #606266;
  font-weight: 500;
  width: 65px;
  flex-shrink: 0;
}

.data-item .value {
  color: #303133;
  margin: 0 10px;
  font-weight: 500;
  flex: 1;
}

.data-item.abnormal .value {
  color: #f56c6c !important;
  font-weight: 600;
}

.data-item.abnormal .label {
  color: #f56c6c;
  font-weight: 600;
}

.data-item.normal::after {
  content: '✓';
  color: #67c23a;
  font-size: 14px;
  font-weight: 700;
  margin-left: 8px;
}

.data-item.abnormal::after {
  content: '!';
  color: #f56c6c;
  font-size: 14px;
  font-weight: 700;
  margin-left: 8px;
}

.data-item .change {
  width: 80px;
  text-align: right;
  font-weight: 600;
  flex-shrink: 0;
}

.data-item .change .up-normal,
.data-item .change .down-normal {
  color: #67c23a;
}

.data-item .change .up-abnormal,
.data-item .change .down-abnormal {
  color: #f56c6c;
  font-weight: 700;
}

.data-item .change .same {
  color: #909399;
}

@media (max-width: 1200px) {
  .timeline-container {
    max-height: calc(100vh - 300px);
  }
}

@media (max-width: 768px) {
  .timeline-item {
    padding-left: 50px;
  }

  .timeline-item::before {
    left: 20px;
    top: 18px;
  }

  .data-item {
    flex-wrap: wrap;
  }

  .data-item .change {
    width: 100%;
    text-align: left;
    margin-top: 5px;
  }

  .timeline-container {
    max-height: calc(100vh - 350px);
  }
}

@media (min-width: 1920px) and (min-height: 1080px) {
  .timeline-container {
    max-height: calc(100vh - 280px);
  }
}

@media (min-width: 1366px) and (max-height: 768px) {
  .timeline-container {
    max-height: calc(100vh - 230px);
  }
}
</style>
